#include "stdafx.h"
#include "matrix.h"
#include "ITMesh.h"
#include "assetfile/handlers/ianim.h"


void OffsetToPointer_CoplanarPoly( COPLANAR_POLYGON **pPoly, void* pBase )
{
	*pPoly = OffsetToPointer(*pPoly, pBase);
	if( (*pPoly)->next )
		OffsetToPointer_CoplanarPoly( &(*pPoly)->next, pBase );
}

void OffsetToPointer_Node( BSPTREE_NODEDATA** pNode, void* pBase )
{
	(*pNode) = OffsetToPointer(*pNode, pBase);
	if( (*pNode)->coplanar )
		OffsetToPointer_CoplanarPoly( &(*pNode)->coplanar, pBase );

	if( (*pNode)->front )
		OffsetToPointer_Node( &(*pNode)->front, pBase );
	if( (*pNode)->back )
		OffsetToPointer_Node( &(*pNode)->back, pBase );
}



//bool CollideNode( BSPTREE_NODEDATA* pNode,



//--------------------------------------------------------------------------------
//	initialize a mesh asset
//--------------------------------------------------------------------------------
void *ITMesh::AssetInit( IAssetFile *pi, const MasterIndexEntry *pme )
{
	ITMesh	*ret;
	void	*pchunk;
	u32		length;
	u32		i;

	ret = (ITMesh*)pi->GetChunk(pme->nameHash,pme->primaryChunk);
	if( ret )
	{
		// restore the pointers that are stored in this chunk
		//ret->pSubObjects= OffsetToPointer(ret->pSubObjects,ret);
		//ret->pRefPoints = OffsetToPointer(ret->pRefPoints,ret);
		ret->vertexDecl = OffsetToPointer(ret->vertexDecl,ret);
		ret->pSubMeshes	= OffsetToPointer(ret->pSubMeshes,ret);
		ret->pMaterials	= OffsetToPointer(ret->pMaterials,ret);

		for( i=0; i<ret->numSubMeshes; i++ )
		{
			ret->pSubMeshes[i].pStrips		= OffsetToPointer(ret->pSubMeshes[i].pStrips,ret);
			//ret->pSubMeshes[i].bsptree.head	= OffsetToPointer(ret->pSubMeshes[i].bsptree.head,ret);
			OffsetToPointer_Node( &ret->pSubMeshes[i].bsptree.head, ret);
		}

		// create the vertex format
		ret->pVFormat = CreateVertexFormat(ret->vertexDecl);

		// get the index chunk
		// create the index buffer
		pchunk = pi->GetChunk(pme->nameHash,*(LOCID*)&ret->pIndices);
		ret->pIndices =CreateIndexBuffer(ret->numIndices,(u16*)pchunk,true);

		for( i=0;i<ret->numStreams;i++ )
		{
			// get the vertex chunk
			pchunk = pi->GetChunk(pme->nameHash,*(LOCID*)&ret->pVertices[i],&length);
			ret->pVertices[i] = CreateVertexBuffer(length,pchunk,true);
		}
		
	}

	return (void*)ret;
}

//--------------------------------------------------------------------------------
//	uninitialize a mesh asset
//--------------------------------------------------------------------------------
void ITMesh::AssetUninit( void *ptr )
{
	ITMesh	*pMesh = (ITMesh *)ptr;
	u32		i;

	if( pMesh->pIndices )
	{
		pMesh->pIndices->Release();
		pMesh->pIndices = 0;
	}
	if( pMesh->pVFormat )
	{
		pMesh->pVFormat->Release();
		pMesh->pVFormat = 0;
	}
	for( i=0;i<pMesh->numStreams;i++ )
	{
		if( pMesh->pVertices[i] )
		{
			pMesh->pVertices[i]->Release();
			pMesh->pVertices[i] = 0;
		}
	}
}

//--------------------------------------------------------------------------------
//	fixup an asset
//--------------------------------------------------------------------------------
void ITMesh::AssetFixup( ASSETFILEMGR *pMgr, const IAssetFile *pFile, void *ptr, const MasterIndexEntry *pEntry )
{
	g_pGame->DoIt( (ITMesh*)ptr );
}

//--------------------------------------------------------------------------------
//	apply an animation to a mesh
//--------------------------------------------------------------------------------
void ITMesh::ApplyAnimation( const ANIMRESULT *result, TRANSMAT *outMats ) const
{
	/*u32				i;
	MESHBONEDATA	*pb;
	VECTOR			v;
	QUAT			q,tq;*/

	if( result )
	{
		
	}
	else
	{
	}
}

//--------------------------------------------------------------------------------------------
//	get a reference point
//--------------------------------------------------------------------------------------------
MATRIX &ITMesh::GetRefMatrix( const ANIMRESULT &animResult, u32 idx, MATRIX &result ) const
{
/*	QUAT			q,r;
	MESHREFPNTDATA	*pref;
	u32				pidx;

	pref = &pRefPoints[idx];
	pidx = pref->parentBone;

	GetBoneMatrix(animResult,pidx,result);
	result.Mult(pref->localOffset,result[3]);

	r.UnCompress(pref->rotOffset);
	q.Multiply(r,animResult.quatList[pidx]);
	q.toMatrix(result);*/
	return result;
}

//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
bool ITMesh::FindRefPoint( const char *name, u32 &pIndex ) const
{
	/*HASH	nameHash = MakeStringHash(name);
	u32		idx;

	for( idx=0;idx<numRefPoints;idx++ )
	{
		if( pRefPoints[idx].nameHash==nameHash )
		{
			pIndex = idx;
			return true;
		}
	}*/
	return false;
}